// Core_Interface.java : behavior editor generated Java class
package com.stottlerhenke.simbionic.engine;

import com.stottlerhenke.simbionic.api.*;
import com.stottlerhenke.simbionic.common.*;
import com.stottlerhenke.simbionic.engine.core.SB_Entity;
import com.stottlerhenke.simbionic.engine.core.SB_ExecutionFrame;
import com.stottlerhenke.simbionic.engine.comm.*;
import com.stottlerhenke.simbionic.engine.core.SB_DelayedAction;
import com.stottlerhenke.simbionic.engine.parser.*;

import java.util.ArrayList;

public class SB_CoreInterface extends SB_Interface
{
// sim revision number
	public static final int SIM_REV = 1;

// actions
  public static final int ACTION_None = -1;
	public static final int ACTION_ArrayAddEntry = 11;
	public static final int ACTION_ArrayAppend = 20;
	public static final int ACTION_ArrayDelete = 10;
	public static final int ACTION_ArrayInsert = 9;
	public static final int ACTION_ArraySet = 8;
	public static final int ACTION_ArraySetMinSize = 19;
	public static final int ACTION_ArraySetSize = 18;
	public static final int ACTION_CreateBBoard = 2;
	public static final int ACTION_DestroyBBoard = 4;
	public static final int ACTION_DestroyEntity = 31;
	public static final int ACTION_DestroyGroup = 7;
	public static final int ACTION_JoinGroup = 5;
	public static final int ACTION_NextMsg = 1;
	public static final int ACTION_PostBBoard = 3;
    public static final int ACTION_PushBehavior = 35;
	public static final int ACTION_QuitGroup = 6;
	public static final int ACTION_Resume = 33;
	public static final int ACTION_Rethrow = 34;
	public static final int ACTION_Retry = 32;
	public static final int ACTION_SendMsg = 0;
	public static final int ACTION_SetBehavior = 28;
	public static final int ACTION_SetEntityGlobal = 27;
	public static final int ACTION_SetUpdateFrequency = 29;
	public static final int ACTION_SetUpdatePriority = 30;
	public static final int ACTION_TableAddCol = 24;
	public static final int ACTION_TableAddRow = 23;
	public static final int ACTION_TableAppend = 25;
	public static final int ACTION_TableDeleteCol = 17;
	public static final int ACTION_TableDeleteRow = 16;
	public static final int ACTION_TableInsertCol = 15;
	public static final int ACTION_TableInsertRow = 14;
	public static final int ACTION_TableSetCol = 26;
	public static final int ACTION_TableSetEntry = 12;
	public static final int ACTION_TableSetMinSize = 22;
	public static final int ACTION_TableSetRow = 13;
	public static final int ACTION_TableSetSize = 21;
	
	public static final int ACTION_TableSort = 36;

// predicates
	public static final int PRED_ArrayCopy = 16;
	public static final int PRED_ArrayGet = 13;
	public static final int PRED_ArrayPop = 15;
	public static final int PRED_ArraySize = 14;
	public static final int PRED_CreateEntity = 23;
	public static final int PRED_GetEntityID = 10;
	public static final int PRED_GetMsgData = 4;
	public static final int PRED_GetMsgSender = 2;
	public static final int PRED_GetMsgType = 3;
	public static final int PRED_If = 9;
	public static final int PRED_IsBBoard = 6;
	public static final int PRED_IsDone = 0;
	public static final int PRED_IsMsg = 1;
	public static final int PRED_IsValid = 7;
	public static final int PRED_NullData = 12;
	public static final int PRED_NullEntityID = 11;
	public static final int PRED_NumMembers = 8;
	public static final int PRED_ReadBBoard = 5;
	public static final int PRED_TableColSize = 18;
	public static final int PRED_TableCopy = 19;
	public static final int PRED_TableGetCol = 22;
	public static final int PRED_TableGetEntry = 21;
	public static final int PRED_TableGetRow = 20;
	public static final int PRED_TableRowSize = 17;
	public static final int PRED_CreateInstance = 24;
	public static final int PRED_IsNull = 25;
	public static final int PRED_IsEntityFinished = 26;
	public static final int PRED_GetEntityName = 27;
	
	public static final int PRED_TableFindFirstMatchingRow = 28;
	public static final int PRED_TableFindAllMatchingRows = 29;
	public static final int PRED_TableFindFirstMatchingRow2 = 30;
	public static final int PRED_TableFindAllMatchingRows2 = 31;
	public static final int PRED_TableFindFirstMatchingRowN = 32;
	public static final int PRED_TableFindAllMatchingRowsN = 33;
	public static final int PRED_TableRowSubset = 34;
	public static final int PRED_TableColumnSubset = 35;
	public static final int PRED_ArrayFindFirst = 36;
	public static final int PRED_ArrayFindAll = 37;
	public static final int PRED_ArraySubset = 38;
	public static final int PRED_EvaluateExpression = 39;

	public SB_CoreInterface (SB_SingletonBook book)
	{
		_book = book;
	}

	protected SB_Entity GetCurrentEntity()
	{
		return _book.getEntityManager().GetEntity( SB_SimInterface.TranslateId(_entityId));
	}
	
	public String getModuleName()
	{
		return "Core";
	}

	public ArrayList getModuleActions()
	{
		ArrayList actions = new ArrayList();

		SB_FuncSpec fd;
		SB_FuncParamSpec fpd;
		ArrayList params;

	    // None
	    params = new ArrayList();
	    fd = new SB_FuncSpec("None", -1, SB_VarType.kInvalid, params);
	    actions.add(fd);

		// ArrayAddEntry
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("element", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayAddEntry", 11, SB_VarType.kInvalid, params);
		actions.add(fd);

		// ArrayAppend
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("source", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("destination", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayAppend", 20, SB_VarType.kInvalid, params);
		actions.add(fd);

		// ArrayDelete
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("position", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayDelete", 10, SB_VarType.kInvalid, params);
		actions.add(fd);

		// ArrayInsert
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("position", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("element", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayInsert", 9, SB_VarType.kInvalid, params);
		actions.add(fd);

		// ArraySet
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("position", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("element", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("ArraySet", 8, SB_VarType.kInvalid, params);
		actions.add(fd);

		// ArraySetMinSize
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("size", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("ArraySetMinSize", 19, SB_VarType.kInvalid, params);
		actions.add(fd);

		// ArraySetSize
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("size", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("ArraySetSize", 18, SB_VarType.kInvalid, params);
		actions.add(fd);

		// CreateBBoard
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("CreateBBoard", 2, SB_VarType.kInvalid, params);
		actions.add(fd);

		// DestroyBBoard
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("DestroyBBoard", 4, SB_VarType.kInvalid, params);
		actions.add(fd);

		// DestroyEntity
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("entityId", SB_ParamDir.kIn, SB_VarType.kEntity);
		params.add(fpd);
		fd = new SB_FuncSpec("DestroyEntity", 31, SB_VarType.kInvalid, params);
		actions.add(fd);

		// DestroyGroup
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("DestroyGroup", 7, SB_VarType.kInvalid, params);
		actions.add(fd);

		// JoinGroup
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("JoinGroup", 5, SB_VarType.kInvalid, params);
		actions.add(fd);

		// NextMsg
		params = new ArrayList();
		fd = new SB_FuncSpec("NextMsg", 1, SB_VarType.kInvalid, params);
		actions.add(fd);

		// PostBBoard
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("key", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("value", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("PostBBoard", 3, SB_VarType.kInvalid, params);
		actions.add(fd);

        // PushBehavior
        params = new ArrayList();
        fpd = new SB_FuncParamSpec("entityId", SB_ParamDir.kIn, SB_VarType.kEntity);
        params.add(fpd);
        fpd = new SB_FuncParamSpec("behavior", SB_ParamDir.kIn, SB_VarType.kString);
        params.add(fpd);
        fpd = new SB_FuncParamSpec("params", SB_ParamDir.kIn, SB_VarType.kArray);
        params.add(fpd);
        fd = new SB_FuncSpec("PushBehavior", 35, SB_VarType.kInvalid, params);
        actions.add(fd);

        // QuitGroup
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("QuitGroup", 6, SB_VarType.kInvalid, params);
		actions.add(fd);

		//	 Resume
		params = new ArrayList();
		fd = new SB_FuncSpec("Resume", 33, SB_VarType.kInvalid, params);
		actions.add(fd);

		// Rethrow
		params = new ArrayList();
		fd = new SB_FuncSpec("Rethrow", 34, SB_VarType.kInvalid, params);
		actions.add(fd);

		// Retry
		params = new ArrayList();
		fd = new SB_FuncSpec("Retry", 32, SB_VarType.kInvalid, params);
		actions.add(fd);
		
		// SendMsg
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("group", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("type", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("msg", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("SendMsg", 0, SB_VarType.kInvalid, params);
		actions.add(fd);

		// SetBehavior
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("entityId", SB_ParamDir.kIn, SB_VarType.kEntity);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("behaviorId", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("params", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("SetBehavior", 28, SB_VarType.kInvalid, params);
		actions.add(fd);

		// SetEntityGlobal
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("entityId", SB_ParamDir.kIn, SB_VarType.kEntity);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("varName", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("value", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("SetEntityGlobal", 27, SB_VarType.kInvalid, params);
		actions.add(fd);

		// SetUpdateFrequency
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("newFreq", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("entityId", SB_ParamDir.kIn, SB_VarType.kEntity);
		params.add(fpd);
		fd = new SB_FuncSpec("SetUpdateFrequency", 29, SB_VarType.kInvalid, params);
		actions.add(fd);

		// SetUpdatePriority
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("newPriority", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("entityId", SB_ParamDir.kIn, SB_VarType.kEntity);
		params.add(fpd);
		fd = new SB_FuncSpec("SetUpdatePriority", 30, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableAddCol
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("table", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("column", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableAddCol", 24, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableAddRow
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("row", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableAddRow", 23, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableAppend
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("source", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("destination", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableAppend", 25, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableDeleteCol
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("columnIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableDeleteCol", 17, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableDeleteRow
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rowIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableDeleteRow", 16, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableInsertCol
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("columnIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("value", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableInsertCol", 15, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableInsertRow
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rowIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("value", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableInsertRow", 14, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableSetCol
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("colIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("column", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableSetCol", 26, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableSetEntry
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rowIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("columnIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("value", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("TableSetEntry", 12, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableSetMinSize
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rows", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("columns", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableSetMinSize", 22, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableSetRow
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rowIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("row", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableSetRow", 13, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableSetSize
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rows", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("columns", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableSetSize", 21, SB_VarType.kInvalid, params);
		actions.add(fd);

		// TableSort
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("sortColumnIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableSort", 36, SB_VarType.kInvalid, params);
		actions.add(fd);
		
		return actions;
	}

	public ArrayList getModulePredicates()
	{
		ArrayList preds = new ArrayList();

		SB_FuncSpec fd;
		SB_FuncParamSpec fpd;
		ArrayList params;

		// ArrayCopy : array
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayCopy", 16, SB_VarType.kArray, params);
		preds.add(fd);

		// ArrayGet : any
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("position", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayGet", 13, SB_VarType.kAny, params);
		preds.add(fd);

		// ArrayPop : any
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kInOut, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayPop", 15, SB_VarType.kAny, params);
		preds.add(fd);

		// ArraySize : integer
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("ArraySize", 14, SB_VarType.kInteger, params);
		preds.add(fd);

		// CreateEntity : entity
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("entityName", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("behaviorId", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("params", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("updateFrequency", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("updatePriority", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("CreateEntity", 23, SB_VarType.kEntity, params);
		preds.add(fd);

//	 CreateInstance : any
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("args", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("CreateInstance", 24, SB_VarType.kAny, params);
		preds.add(fd);

		// GetEntityID : entity
		params = new ArrayList();
		fd = new SB_FuncSpec("GetEntityID", 10, SB_VarType.kEntity, params);
		preds.add(fd);

//		 GetEntityName : string
		params = new ArrayList();
		fd = new SB_FuncSpec("GetEntityName", 27, SB_VarType.kString, params);
		preds.add(fd);
		
		// GetMsgData : any
		params = new ArrayList();
		fd = new SB_FuncSpec("GetMsgData", 4, SB_VarType.kAny, params);
		preds.add(fd);

		// GetMsgSender : entity
		params = new ArrayList();
		fd = new SB_FuncSpec("GetMsgSender", 2, SB_VarType.kEntity, params);
		preds.add(fd);

		// GetMsgType : integer
		params = new ArrayList();
		fd = new SB_FuncSpec("GetMsgType", 3, SB_VarType.kInteger, params);
		preds.add(fd);

		// If : any
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("condition", SB_ParamDir.kIn, SB_VarType.kBoolean);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("value1", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("value2", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("If", 9, SB_VarType.kAny, params);
		preds.add(fd);

		// IsBBoard : boolean
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("IsBBoard", 6, SB_VarType.kBoolean, params);
		preds.add(fd);

		// IsDone : boolean
		params = new ArrayList();
		fd = new SB_FuncSpec("IsDone", 0, SB_VarType.kBoolean, params);
		preds.add(fd);

		// IsMsg : boolean
		params = new ArrayList();
		fd = new SB_FuncSpec("IsMsg", 1, SB_VarType.kBoolean, params);
		preds.add(fd);

		//	 IsNull : boolean
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aClassObject", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("IsNull", 25, SB_VarType.kBoolean, params);
		preds.add(fd);
		
		//	 IsEntityFinished : boolean
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("entity", SB_ParamDir.kIn, SB_VarType.kEntity);
		params.add(fpd);
		fd = new SB_FuncSpec("IsEntityFinished", 26, SB_VarType.kBoolean, params);
		preds.add(fd);

		// IsValid : boolean
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("var", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("IsValid", 7, SB_VarType.kBoolean, params);
		preds.add(fd);

		// NullData : data
		params = new ArrayList();
		fd = new SB_FuncSpec("NullData", 12, SB_VarType.kData, params);
		preds.add(fd);

		// NullEntityID : entity
		params = new ArrayList();
		fd = new SB_FuncSpec("NullEntityID", 11, SB_VarType.kEntity, params);
		preds.add(fd);

		// NumMembers : integer
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("NumMembers", 8, SB_VarType.kInteger, params);
		preds.add(fd);

		// ReadBBoard : any
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("name", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("key", SB_ParamDir.kIn, SB_VarType.kString);
		params.add(fpd);
		fd = new SB_FuncSpec("ReadBBoard", 5, SB_VarType.kAny, params);
		preds.add(fd);

		// TableColSize : integer
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableColSize", 18, SB_VarType.kInteger, params);
		preds.add(fd);

		// TableCopy : table
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableCopy", 19, SB_VarType.kArray, params);
		preds.add(fd);

		// TableGetCol : array
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("column", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableGetCol", 22, SB_VarType.kArray, params);
		preds.add(fd);

		// TableGetEntry : any
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rowIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("columnIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableGetEntry", 21, SB_VarType.kAny, params);
		preds.add(fd);

		// TableGetRow : array
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rowIndex", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fd = new SB_FuncSpec("TableGetRow", 20, SB_VarType.kArray, params);
		preds.add(fd);

		// TableRowSize : integer
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableRowSize", 17, SB_VarType.kInteger, params);
		preds.add(fd);

		// TableFindFirstMatchingRow
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumn", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("TableFindFirstMatchingRow", 28, SB_VarType.kInteger, params);
		preds.add(fd);

		// TableFindAllMatchingRows
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumn", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("TableFindAllMatchingRows", 29, SB_VarType.kArray, params);
		preds.add(fd);

		// TableFindFirstMatchingRow2
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumn1", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue1", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumn2", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue2", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("TableFindFirstMatchingRow2", 30, SB_VarType.kInteger, params);
		preds.add(fd);

		// TableFindAllMatchingRows2
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumn1", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue1", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumn2", SB_ParamDir.kIn, SB_VarType.kInteger);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue2", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("TableFindAllMatchingRows2", 31, SB_VarType.kArray, params);
		preds.add(fd);

		// TableFindFirstMatchingRowN
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumns", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValues", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableFindFirstMatchingRowN", 32, SB_VarType.kInteger, params);
		preds.add(fd);

		// TableFindAllMatchingRowsN
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("aTable", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("selectionColumns", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValues", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableFindAllMatchingRowsN", 33, SB_VarType.kArray, params);
		preds.add(fd);

		// TableRowSubset
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("tableIn", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("rowIndexes", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableRowSubset", 34, SB_VarType.kArray, params);
		preds.add(fd);

		// TableColumnSubset
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("tableIn", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("columnIndexes", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("TableColumnSubset", 35, SB_VarType.kArray, params);
		preds.add(fd);

		// ArrayFindFirst
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayFindFirst", 36, SB_VarType.kInteger, params);
		preds.add(fd);

		// ArrayFindAll
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("anArray", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("matchValue", SB_ParamDir.kIn, SB_VarType.kAny);
		params.add(fpd);
		fd = new SB_FuncSpec("ArrayFindAll", 37, SB_VarType.kArray, params);
		preds.add(fd);

		// ArraySubset
		params = new ArrayList();
		fpd = new SB_FuncParamSpec("arrayIn", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fpd = new SB_FuncParamSpec("positions", SB_ParamDir.kIn, SB_VarType.kArray);
		params.add(fpd);
		fd = new SB_FuncSpec("ArraySubset", 38, SB_VarType.kArray, params);
		preds.add(fd);

		return preds;
	}
	
	public void doAction(int actionId, long entityId, ArrayList params) throws SB_Exception
	{
		_entityId = entityId;
		
		switch (actionId)
		{
		case ACTION_None:
			break;
		case ACTION_ArrayAddEntry:
			ArrayAddEntry((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_ArrayAppend:
			ArrayAppend((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_ArrayDelete:
			ArrayDelete((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_ArrayInsert:
			ArrayInsert((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_ArraySet:
			ArraySet((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_ArraySetMinSize:
			ArraySetMinSize((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_ArraySetSize:
			ArraySetSize((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_CreateBBoard:
			CreateBBoard((SB_Param)params.get(0));
			break;
		case ACTION_DestroyBBoard:
			DestroyBBoard((SB_Param)params.get(0));
			break;
		case ACTION_DestroyEntity:
			DestroyEntity((SB_Param)params.get(0));
			break;
		case ACTION_DestroyGroup:
			DestroyGroup((SB_Param)params.get(0));
			break;
		case ACTION_JoinGroup:
			JoinGroup((SB_Param)params.get(0));
			break;
		case ACTION_NextMsg:
			NextMsg();
			break;
		case ACTION_PostBBoard:
			PostBBoard((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
        case ACTION_PushBehavior:
            PushBehavior((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
            break;
		case ACTION_QuitGroup:
			QuitGroup((SB_Param)params.get(0));
			break;
		case ACTION_Resume:
			Resume();
			break;
		case ACTION_Rethrow:
			Rethrow();
			break;
		case ACTION_Retry:
			Retry();
			break;			
		case ACTION_SendMsg:
			SendMsg((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_SetBehavior:
			SetBehavior((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_SetEntityGlobal:
			SetEntityGlobal((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_SetUpdateFrequency:
			SetUpdateFrequency((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_SetUpdatePriority:
			SetUpdatePriority((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_TableAddCol:
			TableAddCol((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_TableAddRow:
			TableAddRow((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_TableAppend:
			TableAppend((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_TableDeleteCol:
			TableDeleteCol((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_TableDeleteRow:
			TableDeleteRow((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
		case ACTION_TableInsertCol:
			TableInsertCol((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_TableInsertRow:
			TableInsertRow((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_TableSetCol:
			TableSetCol((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_TableSetEntry:
			TableSetEntry((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2), (SB_Param)params.get(3));
			break;
		case ACTION_TableSetMinSize:
			TableSetMinSize((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_TableSetRow:
			TableSetRow((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
		case ACTION_TableSetSize:
			TableSetSize((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			break;
			
		case ACTION_TableSort:
			tableSort((SB_Param)params.get(0), (SB_Param)params.get(1));
			break;
			
		default:
			// unknown action
			break;
		}
	}

	public SB_Param doPredicate(int predId, long entityId, ArrayList params) throws SB_Exception
	{
		_entityId = entityId;
		
		switch (predId)
		{
		case PRED_ArrayCopy:
			return ArrayCopy((SB_Param)params.get(0));
		case PRED_ArrayGet:
			return ArrayGet((SB_Param)params.get(0), (SB_Param)params.get(1));
		case PRED_ArrayPop:
			return ArrayPop((SB_Param)params.get(0));
		case PRED_ArraySize:
			return ArraySize((SB_Param)params.get(0));
		case PRED_CreateEntity:
			return CreateEntity((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2), (SB_Param)params.get(3), (SB_Param)params.get(4));
		case PRED_CreateInstance:
			return CreateInstance((SB_Param)params.get(0), (SB_Param)params.get(1));
		case PRED_GetEntityID:
			return GetEntityID();
		case PRED_GetEntityName:
		    return GetEntityName();
		case PRED_GetMsgData:
			return GetMsgData();
		case PRED_GetMsgSender:
			return GetMsgSender();
		case PRED_GetMsgType:
			return GetMsgType();
		case PRED_If:
			return If((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
		case PRED_IsBBoard:
			return IsBBoard((SB_Param)params.get(0));
		case PRED_IsDone:
			return IsDone();
		case PRED_IsMsg:
			return IsMsg();
		case PRED_IsNull:
			return IsNull((SB_Param)params.get(0));
		case PRED_IsEntityFinished:
		    return IsEntityFinished((SB_Param)params.get(0));
		case PRED_IsValid:
			return IsValid((SB_Param)params.get(0));
		case PRED_NullData:
			return NullData();
		case PRED_NullEntityID:
			return NullEntityID();
		case PRED_NumMembers:
			return NumMembers((SB_Param)params.get(0));
		case PRED_ReadBBoard:
			return ReadBBoard((SB_Param)params.get(0), (SB_Param)params.get(1));
		case PRED_TableColSize:
			return TableColSize((SB_Param)params.get(0));
		case PRED_TableCopy:
			return TableCopy((SB_Param)params.get(0));
		case PRED_TableGetCol:
			return TableGetCol((SB_Param)params.get(0), (SB_Param)params.get(1));
		case PRED_TableGetEntry:
			return TableGetEntry((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
		case PRED_TableGetRow:
			return TableGetRow((SB_Param)params.get(0), (SB_Param)params.get(1));
		case PRED_TableRowSize:
			return TableRowSize((SB_Param)params.get(0));
			
		case PRED_TableFindFirstMatchingRow:
			return tableFindFirstMatchingRow((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			
		case PRED_TableFindAllMatchingRows:
			return tableFindAllMatchingRows((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			
		case PRED_TableFindFirstMatchingRow2:
			return tableFindFirstMatchingRow2((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2), (SB_Param)params.get(3), (SB_Param)params.get(4));
			
		case PRED_TableFindAllMatchingRows2:
			return tableFindAllMatchingRows2((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2), (SB_Param)params.get(3), (SB_Param)params.get(4));
			
		case PRED_TableFindFirstMatchingRowN:
			return tableFindFirstMatchingRowN((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			
		case PRED_TableFindAllMatchingRowsN:
			return tableFindAllMatchingRowsN((SB_Param)params.get(0), (SB_Param)params.get(1), (SB_Param)params.get(2));
			
		case PRED_TableRowSubset:
			return tableRowSubset((SB_Param)params.get(0), (SB_Param)params.get(1));
			
		case PRED_TableColumnSubset:
			return tableColumnSubset((SB_Param)params.get(0), (SB_Param)params.get(1));
			
		case PRED_ArrayFindFirst:
			return arrayFindFirst((SB_Param)params.get(0), (SB_Param)params.get(1));
			
		case PRED_ArrayFindAll:
			return arrayFindAll((SB_Param)params.get(0), (SB_Param)params.get(1));
			
		case PRED_ArraySubset:
			return arraySubset((SB_Param)params.get(0), (SB_Param)params.get(1));
			
		case PRED_EvaluateExpression:
			return evaluateExpression((SB_Param)params.get(0));

		default:
			// unknown predicate
			return new SB_Param();
		}
	}

	// ---- Action Implementations

	/**
	 * Inserts the given element at the end of the given
	 * @param anArray : array [in/out]
	 * @param element : any [in]
	 */
	void ArrayAddEntry(SB_Param anArray, SB_Param element) throws SB_Exception
	{
		anArray.arrayAdd(element);
	}

	/**
	 * Append a source array to the
	 * @param source : array [in]
	 * @param destination : array [in/out]
	 */
	void ArrayAppend(SB_Param source, SB_Param destination) throws SB_Exception
	{
		destination.appendArray(source);
	}

	/**
	 * Deletes the element at the specified position from the
	 * @param anArray : array [in/out]
	 * @param position : integer [in]
	 */
	void ArrayDelete(SB_Param anArray, SB_Param position) throws SB_Exception
	{
		anArray.arrayDelete(position.getInteger());
	}

	/**
	 * Inserts the given element into the given array at the specified
	 * position.
	 * @param anArray : array [in/out]
	 * @param position : integer [in]
	 * @param element : any [in]
	 */
	void ArrayInsert(SB_Param anArray, SB_Param position, SB_Param element)
	throws SB_Exception
	{
		anArray.arrayInsert(position.getInteger(), element);
	}

	/**
	 * Sets the array element at the specified position to the
	 * specified
	 * @param anArray : array [in/out]
	 * @param position : integer [in]
	 * @param element : any [in]
	 */
	void ArraySet(SB_Param anArray, SB_Param position, SB_Param element)
		throws SB_Exception
	{
		anArray.arraySet(position.getInteger(), element);
	}

	/**
	 * The size of the array will be at least as large indicated. If
	 * more items already exist they will remain in the
	 * @param anArray : array [in/out]
	 * @param size : integer [in]
	 */
	void ArraySetMinSize(SB_Param anArray, SB_Param size)
		throws SB_Exception
	{
		anArray.setMinimumArraySize(size.getInteger());
	}
	
	/**
	 * Set the size of the array. Items greater than the size are
	 * @param anArray : array [in/out]
	 * @param size : integer [in]
	 */
	void ArraySetSize(SB_Param anArray, SB_Param size)
		throws SB_Exception
	{
		anArray.setArraySize(size.getInteger());
	}

	/**
	 * Creates a blackboard with the specified
	 * @param name : string [in]
	 */
	void CreateBBoard(SB_Param name) throws SB_Exception
	{
		GetCurrentEntity().GetCommLink().CreateBBoard(name.getString(), _book.getLogger());
	}

	/**
	 * Destroys the named
	 * @param name : string [in]
	 */
	void DestroyBBoard(SB_Param name) throws SB_Exception
	{
		GetCurrentEntity().GetCommLink().DestroyBBoard(name.getString());
	}

	/**
	 * @param entityId : entity [in]
	 */
	void DestroyEntity(SB_Param entityId) throws SB_Exception
	{
		ArrayList variables = new ArrayList();
		variables.add(SB_SimInterface.ConvertParam(SB_VarType.kEntity, entityId, _book));
    SB_DelayedAction action = new SB_DelayedAction(ACTION_DestroyEntity, variables, false);
    _book.queueDelayedAction(action);
	}

	/**
	 * Destroy the named
	 * @param name : string [in]
	 */
	void DestroyGroup(SB_Param name) throws SB_Exception
	{
		GetCurrentEntity().GetCommLink().DestroyGroup(name.getString());
	}

	/**
	 * Enrolls this entity in the named group.  If that group does not
	 * exist, it is
	 * @param name : string [in]
	 */
	void JoinGroup(SB_Param name) throws SB_Exception
	{
		GetCurrentEntity().GetCommLink().JoinGroup(name.getString());
	}

	/**
	 * Discards the topmost message in the
	 */
	void NextMsg()
	{
		GetCurrentEntity().GetCommLink().NextMsg();
	}

	/**
	 * Posts a key-value pair to the specified
	 * @param name : string [in]
	 * @param key : string [in]
	 * @param value : any [in]
	 */
	void PostBBoard(SB_Param name, SB_Param key, SB_Param value) throws SB_Exception
	{
		GetCurrentEntity().GetCommLink().PostBBoard(name.getString(), key.getString(), SB_SimInterface.ConvertParamAuto(value, _book));
	}

    /**
     * Invokes the specified behavior
     * @param entityId : entity [in]
     * @param behaviorId : string [in]
     * @param params : array [in]
     */
    void PushBehavior(SB_Param entityId, SB_Param behaviorId, SB_Param params)
    throws SB_Exception
    {
         ArrayList variables = new ArrayList();
         variables.add( SB_SimInterface.ConvertParam(SB_VarType.kEntity, entityId, _book) );
         variables.add( SB_SimInterface.ConvertParam(SB_VarType.kString, behaviorId, _book) );
    
         //An SB_VarArray filled with SB_Param objects
         ArrayList varParams = new ArrayList( params.getArray() );
         ArrayList list = SB_SimInterface.ConvertParams( varParams, _book );
         variables.add(list);
    
         SB_DelayedAction action = new SB_DelayedAction(ACTION_PushBehavior, variables, false);
         _book.queueDelayedAction(action);      
    }

    /**
	 * Removes this entity from the named
	 * @param name : string [in]
	 */
	void QuitGroup(SB_Param name) throws SB_Exception
	{
		GetCurrentEntity().GetCommLink().QuitGroup(name.getString());
	}

	/**
	 * The Resume action causes execution to resume at the node where
	 * the exception was thrown without attempting to retry execution
	 */
	void Resume() throws SB_Exception
	{
		GetCurrentEntity().GetState().GetExecStack().Resume();
	}

	/**
	 * The Rethrow action rethrows the current exception down the stack
	 * to the current behavior's invoking behavior and then terminates
	 * the current behavior just as if a final node had been
	 */
	void Rethrow() throws SB_Exception
	{
		GetCurrentEntity().GetState().GetExecStack().Rethrow();
	}

	/**
	 * The Retry action causes behavior execution to jump to the node
	 * in this behavior where the exception was thrown, executing that
	 * node exactly as if it had just become the current node in normal
	 * fashion.  That is, the bindings for that node will be evaluated,
	 */
	void Retry() throws SB_Exception
	{
		GetCurrentEntity().GetState().GetExecStack().Retry();
	}

	
	/**
	 * Sends a message to the specified group, where a message consists
	 * of a numerical type and an arbitrary variable
	 * @param group : string [in]
	 * @param type : integer [in]
	 * @param msg : any [in]
	 */
	void SendMsg(SB_Param group, SB_Param type, SB_Param msg)
		throws SB_Exception
	{
		SB_CommMsg newmsg = new SB_CommMsg( 	GetCurrentEntity().GetId(), group.getString(), type.getInteger(), SB_SimInterface.ConvertParamAuto(msg, _book) );
		GetCurrentEntity().GetCommLink().Send(newmsg);
	}

	/**
	 * @param entityId : entity [in]
	 * @param behaviorId : string [in]
	 * @param params : array [in]
	 */
	void SetBehavior(SB_Param entityId, SB_Param behaviorId, SB_Param params)
	throws SB_Exception
	{
		 ArrayList variables = new ArrayList();
		 variables.add( SB_SimInterface.ConvertParam(SB_VarType.kEntity, entityId, _book) );
		 variables.add( SB_SimInterface.ConvertParam(SB_VarType.kString, behaviorId, _book) );
		 
		 //An SB_VarArray filled with SB_Param objects
		 ArrayList varParams = new ArrayList( params.getArray() );
		 ArrayList list = SB_SimInterface.ConvertParams( varParams, _book );
		 variables.add(list);
		 
		 SB_DelayedAction action = new SB_DelayedAction(ACTION_SetBehavior, variables, false);
		 _book.queueDelayedAction(action);		
	}

	/**
	 * @param entityId : entity [in]
	 * @param varName : string [in]
	 * @param value : any [in]
	 */
	void SetEntityGlobal(SB_Param entityId, SB_Param varName, SB_Param value)
	throws SB_Exception
	{
		ArrayList variables = new ArrayList();
		variables.add( SB_SimInterface.ConvertParam(SB_VarType.kEntity, entityId, _book) );
    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kString, varName, _book) );

    //Deep copy the value if it is an array
    if( value.getType() == SB_ParamType.kSB_Array )
    {
    	SB_VarArray varArray = new SB_VarArray( value.getArray() );
    	SB_VarArray newVarArray = new SB_VarArray();
    	newVarArray.deepCopy(varArray);
      variables.add(newVarArray.GetValue());
    }
    else
      variables.add(SB_SimInterface.ConvertParamAuto(value, _book));

    SB_DelayedAction action = new SB_DelayedAction(ACTION_SetEntityGlobal, variables, false);
    _book.queueDelayedAction(action);
	}

	/**
	 * @param newFreq : integer [in]
	 * @param entityId : entity [in]
	 */
	void SetUpdateFrequency(SB_Param newFreq, SB_Param entityId)
	throws SB_Exception
	{
		ArrayList variables = new ArrayList();
    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kInteger, newFreq, _book));
    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kEntity, entityId, _book));
    SB_DelayedAction action = new SB_DelayedAction(ACTION_SetUpdateFrequency, variables, false);
    _book.queueDelayedAction(action);
	}

	/**
	 * @param newPriority : integer [in]
	 * @param entityId : entity [in]
	 */
	void SetUpdatePriority(SB_Param newPriority, SB_Param entityId)
	throws SB_Exception
	{
		ArrayList variables = new ArrayList();
    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kInteger, newPriority, _book));
    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kEntity, entityId, _book));
    SB_DelayedAction action = new SB_DelayedAction(ACTION_SetUpdateFrequency, variables, false);
    _book.queueDelayedAction(action);
	}

	/**
	 * Add a column to the end of the
	 * @param table : table [in/out]
	 * @param column : array [in]
	 */
	void TableAddCol(SB_Param table, SB_Param column) throws SB_Exception
	{
    table.tableAddColumn(column);
	}

	/**
	 * Add a row to the end of the
	 * @param aTable : table [in/out]
	 * @param row : array [in]
	 */
	void TableAddRow(SB_Param aTable, SB_Param row) throws SB_Exception
	{
		aTable.tableAddRow(row);
	}

	/**
	 * Append the source table rows to the destination
	 * @param source : table [in]
	 * @param destination : table [in/out]
	 */
	void TableAppend(SB_Param source, SB_Param destination) throws SB_Exception
	{
		destination.appendTable(source);
	}

	/**
	 * Deletes the column at the specified position from the table.
	 * All elements with column index  > column before the deletion
	 * will have column index = index-1 after the deletion.  The table
	 * column size will also be decremented by
	 * @param aTable : table [in/out]
	 * @param columnIndex : integer [in]
	 */
	void TableDeleteCol(SB_Param aTable, SB_Param columnIndex)
		throws SB_Exception
	{
		aTable.tableDeleteColumn(columnIndex.getInteger());
	}

	/**
	 * Deletes the row at the specified position from the table.  All
	 * elements with row index  > row before the deletion will have row
	 * index = index-1 after the deletion.  The table row size will
	 * also be decremented by
	 * @param aTable : table [in/out]
	 * @param rowIndex : integer [in]
	 */
	void TableDeleteRow(SB_Param aTable, SB_Param rowIndex)
	throws SB_Exception
	{
		aTable.tableDeleteRow(rowIndex.getInteger());
	}

	/**
	 * Inserts a new column into the given table before the given
	 * column.  All elements in the new column will be assigned
	 * initValue. All elements with column index >= column before the
	 * insertion will have column index = index+1 after the insertion.
	 * The table's column size will also be incremented by
	 * @param aTable : table [in/out]
	 * @param columnIndex : integer [in]
	 * @param value : array [in]
	 */
	void TableInsertCol(SB_Param aTable, SB_Param columnIndex, SB_Param value)
	throws SB_Exception
	{
		aTable.tableInsertColumn(columnIndex.getInteger(), value);
	}

	/**
	 * Inserts a new row into the given table before the given row. All
	 * elements in the new row will be assigned initValue.  All
	 * elements with row index >= row before the insertion will have
	 * row index = index+1 after the insertion. The table's row size
	 * will also be incremented by
	 * @param aTable : table [in]
	 * @param rowIndex : integer [in]
	 * @param value : array [in]
	 */
	void TableInsertRow(SB_Param aTable, SB_Param rowIndex, SB_Param value)
	throws SB_Exception
	{
		aTable.tableInsertRow(rowIndex.getInteger(), value);
	}

	/**
	 * Set a column of the table to the new
	 * @param aTable : table [in/out]
	 * @param colIndex : integer [in]
	 * @param column : array [in]
	 */
	void TableSetCol(SB_Param aTable, SB_Param colIndex, SB_Param column)
	throws SB_Exception
	{
		aTable.tableSetColumn(colIndex.getInteger(), column);
	}

	/**
	 * Set the indexed entry to the given
	 * @param aTable : table [in/out]
	 * @param rowIndex : integer [in]
	 * @param columnIndex : integer [in]
	 * @param value : any [in]
	 */
	void TableSetEntry(SB_Param aTable, SB_Param rowIndex, SB_Param columnIndex, SB_Param value)
	throws SB_Exception
	{
		aTable.tableSetEntry(rowIndex.getInteger(), columnIndex.getInteger(), value);
	}

	/**
	 * Set the minimum size of the table. If more items already exist
	 * in the table they will not be
	 * @param aTable : table [in/out]
	 * @param rows : integer [in]
	 * @param columns : integer [in]
	 */
	void TableSetMinSize(SB_Param aTable, SB_Param rows, SB_Param columns)
	throws SB_Exception
	{
		aTable.setMinimumTableSize(rows.getInteger(), columns.getInteger());
	}

	/**
	 * Set a row of the table to the new
	 * @param aTable : table [in/out]
	 * @param rowIndex : integer [in]
	 * @param row : array [in]
	 */
	void TableSetRow(SB_Param aTable, SB_Param rowIndex, SB_Param row)
	throws SB_Exception
	{
		aTable.tableSetRow(rowIndex.getInteger(), row);
	}

	/**
	 * Set the absolute sizes for the table, truncating if more items
	 * exist.
	 * @param aTable : table [in/out]
	 * @param rows : integer [in]
	 * @param columns : integer [in]
	 */
	void TableSetSize(SB_Param aTable, SB_Param rows, SB_Param columns)
	throws SB_Exception
	{
		aTable.setTableSize(rows.getInteger(), columns.getInteger());
	}
	
	/**
	 * Sorts the rows in aTable by the values in column sortColumnIndex.
	 * @param aTable	table [in/out]
	 * @param sortColumnIndex	the index of the column used for sorting
	 * @throws SB_Exception
	 */
	void tableSort(SB_Param aTable, SB_Param sortColumnIndex) throws SB_Exception
	{
		aTable.sortTable(sortColumnIndex.getInteger());
	}

	// ---- Predicate Implementations

	/**
	 * Returns a deep copy of the given array. This is a copy of the
	 * original array, where every element in the array is also a
	 * @param anArray : array [in]
	 * @return array
	 */
	SB_Param ArrayCopy(SB_Param anArray) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		retVal.setType(SB_ParamType.kSB_Array);
		retVal.copyArray(anArray);

		return retVal;
	}

	/**
	 * Returns the element at the given position of the given
	 * @param anArray : array [in]
	 * @param position : integer [in]
	 * @return any
	 */
	SB_Param ArrayGet(SB_Param anArray, SB_Param position)
	throws SB_Exception
	{
		return anArray.getArrayEntry(position.getInteger());
	}

	/**
	 * Deletes the element at the end of the given array.  Returns the
	 * @param anArray : array [in/out]
	 * @return any
	 */
	SB_Param ArrayPop(SB_Param anArray) throws SB_Exception
	{
		// your ArrayPop implementation here
		int lastIndex = anArray.getArraySize();
		if( lastIndex > 0 )
		{
			SB_Param retVal = anArray.getArrayEntry(lastIndex - 1);
			anArray.arrayDelete(lastIndex - 1);
			return retVal;
		}
		else
			throw new SB_Exception("Exception in SB_Param.ArrayPop: Attemped to pop from an empty array");
	}

	/**
	 * Returns the number of elements in the
	 * @param anArray : array [in]
	 * @return integer
	 */
	SB_Param ArraySize(SB_Param anArray) throws SB_Exception
	{
		return new SB_Param(anArray.getArraySize());
	}

	/**
	 * @param entityName : string [in]
	 * @param behaviorId : string [in]
	 * @param params : array [in]
	 * @param updateFrequency : integer [in]
	 * @param updatePriority : integer [in]
	 * @return entity
	 */
	SB_Param CreateEntity(SB_Param entityName, SB_Param behaviorId, SB_Param params, SB_Param updateFrequency, SB_Param updatePriority)
	throws SB_Exception
	{
	    SB_Param retVal = new SB_Param();
	    retVal.setType(SB_ParamType.kSB_Entity);
	    
	    SB_ID newId  = _book.getEntityManager().GetIdDispenser().ClaimId(EIdType.kEntityId);
	    
	    ArrayList variables = new ArrayList();
	    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kString, entityName, _book) );
	    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kString, behaviorId, _book) );
	    
	    //An SB_VarArray filled with SB_Param objects
	    ArrayList varParams = new ArrayList( params.getArray() );
	    ArrayList list = SB_SimInterface.ConvertParams( varParams, _book );
	    variables.add(list);
	    
	    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kInteger, updateFrequency, _book) );
	    variables.add( SB_SimInterface.ConvertParam(SB_VarType.kInteger,updatePriority, _book) );
	    variables.add( new SB_VarEntity(newId) );
	    
	    SB_DelayedAction action = new SB_DelayedAction(PRED_CreateEntity, variables, true);
	    
	    _book.queueDelayedAction(action);
	    
	    retVal.setEntity(SB_SimInterface.TranslateId(newId));
	    
	    return retVal;

	}

	/**
	 * Create a new class
	 * @param name : string [in]
	 * @param args : array [in]
	 * @return any
	 */
	SB_Param CreateInstance(SB_Param name, SB_Param args) throws SB_Exception
	{
	  ArrayList list = SB_SimInterface.ConvertParams( new ArrayList(args.getArray()), _book );
		SB_Variable var = SB_VarClass.createInstance(_book, name.getString(), list);
		return var.getSB_Param();
	}

	/**
	 * Returns the SimBionic ID of the current
	 * @return entity
	 */
	SB_Param GetEntityID()
	{
		return new SB_Param(SB_SimInterface.TranslateId(_book.getEntityManager().GetCurrentEntity()));
	}

	/**
	 * Returns the SimBionic name of the current entity
	 * @return string
	 */
	SB_Param GetEntityName() throws SB_Exception
	{
	    SB_Entity entity = _book.getEntityManager().GetEntity(_book.getEntityManager().GetCurrentEntity());
		
	    String name = "";
	    if( entity != null )
	        name = entity.GetName();
	    
		return new SB_Param(name);
	}
	
	/**
	 * Returns the data (a single variable value) associated with the
	 * topmost message in the
	 * @return any
	 */
	SB_Param GetMsgData()
	throws SB_Exception
	{
		SB_CommMsg msg = GetCurrentEntity().GetCommLink().CurrentMsg();
		return msg.GetData().Clone().getSB_Param();
	}

	/**
	 * Returns the sender of the topmost message in the
	 * @return entity
	 */
	SB_Param GetMsgSender()
	{
		SB_CommMsg msg = GetCurrentEntity().GetCommLink().CurrentMsg();
		return new SB_Param( SB_SimInterface.TranslateId(msg.GetSender()) );
	}

	/**
	 * Returns the type of the topmost message in the
	 * @return integer
	 */
	SB_Param GetMsgType()
	{
		SB_CommMsg msg = GetCurrentEntity().GetCommLink().CurrentMsg();
		return new SB_Param(msg.GetMsgType());
	}

	/**
	 * If condition is true, returns parameter value1, otherwise
	 * returns parameter
	 * @param condition : boolean [in]
	 * @param value1 : any [in]
	 * @param value2 : any [in]
	 * @return any
	 */
	SB_Param If(SB_Param condition, SB_Param value1, SB_Param value2)
	throws SB_Exception
	{
		SB_Param retVal;
		
		if (condition.getBoolean())
    	// return value1
      retVal = value1.cloneParam();
    else
    	// return value2
      retVal = value2.cloneParam();
      
		return retVal;
	}

	/**
	 * Returns true if the named blackboard exists, false otherwise.
	 * Allows entities to "block" until a needed blackboard is created
	 * (e.g., by a
	 * @param name : string [in]
	 * @return boolean
	 */
	SB_Param IsBBoard(SB_Param name) throws SB_Exception
	{
		return new SB_Param(GetCurrentEntity().GetCommLink().IsBBoard(name.getString()));
	}

	/**
	 * Indicates whether the behavior invoked by the frame whose transitions are currently
     * being checked has completed.
	 * Return true if behavior is finished, false
	 * @return boolean
	 */
	SB_Param IsDone()
	{
        SB_ExecutionFrame checkedFrame = GetCurrentEntity().GetState().GetExecStack().getCheckedFrame();
        if (checkedFrame == null)
            return new SB_Param(false);
		return new SB_Param( checkedFrame.IsInvokedDone() );
	}

	/**
	 * Returns true if there is a message in the queue, false
	 * @return boolean
	 */
	SB_Param IsMsg()
	{
		return new SB_Param(GetCurrentEntity().GetCommLink().CurrentMsg() != null);
	}

	/**
	 * Returns true if the value of the class variable object is null,
	 * false
	 * @param aClassObject : any [in]
	 * @return boolean
	 */
	SB_Param IsNull(SB_Param aClassObject) throws SB_Exception
	{
		return new SB_Param(aClassObject.getData() == null);
	}
	
	/**
	 * Returns true if the specified entity's stack is empty, false
	 * otherwise.
	 * @param entity : entity [in]
	 * @return boolean
	 */
	SB_Param IsEntityFinished(SB_Param entity) throws SB_Exception
	{
		return new SB_Param(_book.getEntityManager().IsEntityFinished(new SB_ID(entity.getEntity())));
	}

	/**
	 * Returns true if the given variable is valid, false
	 * @param var : any [in]
	 * @return boolean
	 */
	SB_Param IsValid(SB_Param var)
	{
		return new SB_Param( var.getType() != SB_ParamType.kSB_Invalid );
	}

	/**
	 * Returns a NULL data value guaranteed to evaluate to false in a
	 * condition.
	 * @return data
	 */
	SB_Param NullData()
	{
			// the zero-argument constructor creates a data variable with value null
      // (can't directly supply null value because it creates ambiguity with copy constructor)
      SB_Param retVal = new SB_Param();
      retVal.setType(SB_ParamType.kSB_Data);
      return retVal;
	}

	/**
	 * Returns an invalid SimBionic ID guaranteed to evaluate to false
	 * in a
	 * @return entity
	 */
	SB_Param NullEntityID()
	{
		return new SB_Param( SB_SimInterface.TranslateId(SB_ID.NULL_ID()) );
	}

	/**
	 * Returns the number of members in the named group.  If the group
	 * does not exist, return
	 * @param name : string [in]
	 * @return integer
	 */
	SB_Param NumMembers(SB_Param name) throws SB_Exception
	{
		return new SB_Param( GetCurrentEntity().GetCommLink().GetNumMembers(name.getString()) );
	}

	/**
	 * Returns the value associated with the specified key on the named
	 * blackboard, or an INVALID variable if no such key
	 * @param name : string [in]
	 * @param key : string [in]
	 * @return any
	 */
	SB_Param ReadBBoard(SB_Param name, SB_Param key) throws SB_Exception
	{
	    SB_Variable retVal = GetCurrentEntity().GetCommLink().ReadBBoard( name.getString(), key.getString() );
	    
	    if( retVal == null )
	    	return new SB_Param();
	    else
	    	return retVal.getSB_Param().cloneParam();
	}

	/**
	 * Returns the number of columns in the
	 * @param aTable : table [in]
	 * @return integer
	 */
	SB_Param TableColSize(SB_Param aTable) throws SB_Exception
	{
		return new SB_Param( aTable.getTableColumnSize() );
	}

	/**
	 * Returns a deep copy of the given
	 * @param aTable : table [in]
	 * @return table
	 */
	SB_Param TableCopy(SB_Param aTable) throws SB_Exception
	{
		SB_Param retVal = new SB_Param();
		retVal.copyArray(aTable);
		return retVal;
	}

	/**
	 * Return a column of the
	 * @param aTable : table [in]
	 * @param column : integer [in]
	 * @return array
	 */
	SB_Param TableGetCol(SB_Param aTable, SB_Param column)
	throws SB_Exception
	{
		return aTable.getTableColumn(column.getInteger());
	}

	/**
	 * Returns the item at the given row and
	 * @param aTable : table [in]
	 * @param rowIndex : integer [in]
	 * @param columnIndex : integer [in]
	 * @return any
	 */
	SB_Param TableGetEntry(SB_Param aTable, SB_Param rowIndex, SB_Param columnIndex)
	throws SB_Exception
	{
		return aTable.getTableEntry(rowIndex.getInteger(), columnIndex.getInteger());
	}

	/**
	 * Get a row of the table as an
	 * @param aTable : table [in]
	 * @param rowIndex : integer [in]
	 * @return array
	 */
	SB_Param TableGetRow(SB_Param aTable, SB_Param rowIndex)
	throws SB_Exception
	{
		return aTable.getTableRow(rowIndex.getInteger());
	}

	/**
	 * Returns the number of rows in the
	 * @param aTable : table [in]
	 * @return integer
	 */
	SB_Param TableRowSize(SB_Param aTable) throws SB_Exception
	{
		return new SB_Param( aTable.getTableRowSize() );
	}

	/**
	 * Returns row1 which equals the first row where 
	 * aTable[row1, selectionColumn] == matchValue.
	 * Returns -1 if no row satisfies this condition.
	 * 
	 * @param aTable	table [in]
	 * @param selectionColumn	the column used for matching
	 * @param matchValue	the value to match against
	 * @return	an integer which is the row index
	 * @throws SB_Exception
	 */
	SB_Param tableFindFirstMatchingRow(SB_Param aTable, 
			SB_Param selectionColumn, 
			SB_Param matchValue) throws SB_Exception
	{
		return new SB_Param(aTable.findTableFirstMatchingRow(selectionColumn.getInteger(), matchValue));
	}
	
	/**
	 * Returns an array which contains all row indexes row1 such that
	 * aTable[row1, selectionColumn] == matchValue.
	 * 
	 * @param aTable	table [in]
	 * @param selectionColumn	the column used for matching
	 * @param matchValue	the value to match against
	 * @return	an array
	 * @throws SB_Exception
	 */
	SB_Param tableFindAllMatchingRows(SB_Param aTable,
			SB_Param selectionColumn,
			SB_Param matchValue) throws SB_Exception
	{
		return new SB_Param(aTable.findTableAllMatchingRows(selectionColumn.getInteger(), matchValue));
	}
	
	/**
	 * Returns row1 which equals the first row where 
	 * aTable[row1, selectionColumn1] == matchValue1 &&
	 * aTable[row1, selectionColumn2] == matchValue2.
	 * Returns -1 if no row satisfies this condition.
	 * 
	 * @param aTable	table [in]
	 * @param selectionColumn1	index of the first column to match
	 * @param matchValue1	the value to match the first column
	 * @param selectionColumn2	index of the second column to match
	 * @param matchValue2	the value to match the second column
	 * @return	an integer row index
	 * @throws SB_Exception
	 */
	SB_Param tableFindFirstMatchingRow2(SB_Param aTable,
			SB_Param selectionColumn1, 
			SB_Param matchValue1,
			SB_Param selectionColumn2,
			SB_Param matchValue2) throws SB_Exception
	{
		return new SB_Param(aTable.findTableFirstMatchingRow2(selectionColumn1.getInteger(), matchValue1, selectionColumn2.getInteger(), matchValue2));
	}
	
	/**
	 * Returns an array which contains all row indexes row1 such that
	 * aTable[row1, selectionColumn1] == matchValue1 &&
	 * aTable[row1, selectionColumn2] == matchValue2.
	 * 
	 * @param aTable	table [in]
	 * @param selectionColumn1	index of the first column to match
	 * @param matchValue1	the value to match the first column
	 * @param selectionColumn2	index of the second column to match
	 * @param matchValue2	the value to match the second column
	 * @return	an array
	 * @throws SB_Exception
	 */
	SB_Param tableFindAllMatchingRows2(SB_Param aTable,
			SB_Param selectionColumn1,
			SB_Param matchValue1,
			SB_Param selectionColumn2,
			SB_Param matchValue2) throws SB_Exception
	{
		return new SB_Param(aTable.findTableAllMatchingRows2(selectionColumn1.getInteger(), matchValue1, selectionColumn2.getInteger(), matchValue2));
	}
	
	/**
	 * Returns row1 which equals the first row where 
	 * table1[row1, selectionColumns[i]] == matchValue[i], for
	 * all i = 1..length(selectionColumns).
	 * Returns -1 if no row satisfies this condition.
	 * 
	 * @param aTable	table [in]
	 * @param selectionColumns	the indices of columns to match
	 * @param matchValues	the values to match
	 * @return	an integer row index
	 * @throws SB_Exception
	 */
	SB_Param tableFindFirstMatchingRowN(SB_Param aTable,
			SB_Param selectionColumns,
			SB_Param matchValues) throws SB_Exception
	{
		return new SB_Param(aTable.findTableFirstMatchingRowN(selectionColumns, matchValues));
	}
	
	/**
	 * Returns an array which contains all row indexes row1 such that
	 * table1[row1, selectionColumns[i]] == matchValue[i], for
	 * all i = 1..length(selectionColumns).
	 * 
	 * @param aTable	table [in]
	 * @param selectionColumns	the indices of columns to match
	 * @param matchValues	the values to match
	 * @return	an array
	 * @throws SB_Exception
	 */
	SB_Param tableFindAllMatchingRowsN(SB_Param aTable,
			SB_Param selectionColumns,
			SB_Param matchValues) throws SB_Exception
	{
		return new SB_Param(aTable.findTableAllMatchingRowsN(selectionColumns, matchValues));
	}
	
	/**
	 * Returns a table, tableOut, such that row i of table = row rowIndexes[i] of 
	 * aTable, for i = 1..length(rowIndexes).
	 * 
	 * @param aTable	table[in]
	 * @param rowIndices	the indices of the rows that is going to be in the subset table
	 * @return	a subset table
	 * @throws SB_Exception
	 */
	SB_Param tableRowSubset(SB_Param aTable, SB_Param rowIndices) throws SB_Exception
	{
		return aTable.getTableRowSubset(rowIndices);
	}
	
	/**
	 * Returns a table, tableOut, such that column i of table = column columnIndexes[i] of 
	 * aTable, for i = 1..length(columnIndexes).
	 * 
	 * @param aTable	table [in]
	 * @param columnIndices the indices of the columns that is going to be in the subset
	 * @return	a subset table
	 * @throws SB_Exception
	 */
	SB_Param tableColumnSubset(SB_Param aTable, SB_Param columnIndices) throws SB_Exception
	{
		return aTable.getTableColumnSubset(columnIndices);
	}
	
	/**
	 * Returns the index position of the first element in anArray that equals matchValue.
	 * 
	 * @param anArray	array [in]
	 * @param matchValue	the value to match against
	 * @return	an integer index
	 * @throws SB_Exception
	 */
	SB_Param arrayFindFirst(SB_Param anArray, SB_Param matchValue) throws SB_Exception
	{
		return new SB_Param(anArray.findArrayFirst(matchValue));
	}
	
	/**
	 * Returns an array of all index positions of elements in anArray that equal matchValue.
	 * 
	 * @param anArray	array [in]
	 * @param matchValue	the value to match against
	 * @return	an array of indices
	 * @throws SB_Exception
	 */
	SB_Param arrayFindAll(SB_Param anArray, SB_Param matchValue) throws SB_Exception
	{
		return new SB_Param(anArray.findArrayAll(matchValue));
	}
	
	/**
	 * Returns an array arrayOut such that arrayOut[i] equals anArray[positions[i]], 
	 * for i = 1..length(positions).
	 * 
	 * @param anArray	array [in]
	 * @param positions	positions of the elements that is going to be in the subset
	 * @return	an array
	 * @throws SB_Exception
	 */
	SB_Param arraySubset(SB_Param anArray, SB_Param positions) throws SB_Exception
	{
		return anArray.getArraySubset(positions);
	}
	
	/**
	 * Evaluates the specified expression and returns the evaluation result.
	 * The expression may refer to local and/or global variables.
	 * @param expression	the string expression
	 * @return	the evaluation result of the expression
	 * @throws SB_Exception
	 */
	SB_Param evaluateExpression(SB_Param expression) throws SB_Exception
	{
		SB_Entity currentEntity = GetCurrentEntity();
		SB_ExecutionFrame contextFrame = currentEntity.GetState().GetExecStack().getCurrentFrame();
		SB_Expression exp = (SB_Expression) _book.getParser().Parse(expression.getString());
		SB_Variable ret = exp.Evaluate(currentEntity, contextFrame);
		return ret.getSB_Param();
	}
	
	private SB_SingletonBook _book;
	private long						 _entityId;
};
